package cn.com.wms.dao.impl;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;

import cn.com.wms.Base.CommonOperate;
import cn.com.wms.Base.FilterInfo;
import cn.com.wms.Base.QueryResult;
import cn.com.wms.Base.pageInfo.PagingBean;
import cn.com.wms.dao.MixedDao;



/**
 * 
 * @author zbzhu
 * 创建日期 2011-7-7
 * 类名      MixedDaoImpl.java
 * 说明   description of the class
 * @param <T>0
 */
@Repository("mixedDao")
public class MixedDaoImpl<T> implements MixedDao<T>{
	protected final Log logger = LogFactory.getLog(this.getClass());
	private SessionFactory sessionFactory;
	private DataSource dataSource;
	private HibernateTemplate hibernateTemplate;
	private JdbcTemplate jdbcTemplate;
	
	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}
	@Autowired
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}
	public DataSource getDataSource() {
		return dataSource;
	}
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	public HibernateTemplate getHibernateTemplate() {
		if(this.hibernateTemplate == null){
			this.hibernateTemplate = new HibernateTemplate(this.sessionFactory);
		}
		return this.hibernateTemplate;
	}
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
	public JdbcTemplate getJdbcTemplate() {
		if(this.jdbcTemplate == null){
			this.jdbcTemplate = new JdbcTemplate(this.dataSource);
		}
		return this.jdbcTemplate;
	}
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	
	public int delete_Or_Update_Hibernate_ComposedQuery(final String composedSQL,final Object[] params){
		int rs = 0;

		rs = ((Integer)this.getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query sqlQuery = session.createSQLQuery(composedSQL);
				if(params != null){
					for(int i=0 ; i<params.length ; i++){
						sqlQuery.setParameter(i, params[i]);
					}
				}
				int rtn = sqlQuery.executeUpdate();
				return rtn;
			}
        })).intValue();
		return rs;
	}
	
	
	public int delete_Or_Update_Hibernate_NamedQuery(final String queryID, final Object[] params){
	    int rs = 0;

	    rs = ((Integer)getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
	      public Object doInHibernate(Session session) throws HibernateException {
	        Query queryCMd = session.getNamedQuery(queryID);
	        String queryString = queryCMd.getQueryString();
	        Query sqlq = session.createSQLQuery(queryString);
	        int length = params.length;
	        for (int i = 0; i < length; ++i) {
	          sqlq.setParameter(i, params[i]);
	        }
	        int rtn = sqlq.executeUpdate();
	        return new Integer(rtn);
	      }
	    })).intValue();

	    return rs;
	}
	
	public int delete_Hibernate_Object(T t){
		int rs = 0;
		this.getHibernateTemplate().delete(t);
		rs = 1;
		return rs;
	}
	
	public int delete_Or_Update_JDBC(String sql){
	    int rs = 0;
	    this.getJdbcTemplate().execute(sql);
	    rs = 1;
	    return rs;
	}
	
	public int delete_Hibernate_Object_ById(Class<? extends T> cls, Serializable id) {
	    int rs = 0;
	    T t = find_ByID_Hibernate_Get(cls, id);
	    if (t != null) {
	      this.getHibernateTemplate().delete(t);
	    }
	    rs = 1;
	    return rs;
	}
	
	public T find_ByID_Hibernate_Get(Class<? extends T> cls, Serializable id){
		T t = null;
	    t = (T)this.getHibernateTemplate().get(cls, id);
	    //添加下面的语句会多发一条查询SQL
//	    if (t != null){
//	      this.getHibernateTemplate().refresh(t); 
//	    }
	    return t;
	}
	
	public T findByID_Hibernate_Load(Class<? extends T> cls, Serializable id){
	    T t = null;
	    t = (T)getHibernateTemplate().load(cls, id);
	    if (t != null)
	    {
	      getHibernateTemplate().refresh(t); 
	    }
	    return t;
	}
	
	public List<T> findAll_Hibernate_ComposedHQL(String composedHQL,Object[] params){
		return (List<T>) this.getHibernateTemplate().find(composedHQL,params);
	}
	
	public List<T> findAll_Hibernate_NamedQuery(String queryID, Object[] params){
	    List<T> list = (List<T>) getHibernateTemplate().findByNamedQuery(queryID, params);
	    return list;
	}
	
	
	public int save_Hibernate_NamedQuery(final String queryID, final Object[] params){
	    int rs = 0;

	    rs = ((Integer)getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
	      public Object doInHibernate(Session session) throws HibernateException {
	        Query queryCMd = session.getNamedQuery(queryID);
	        String queryString = queryCMd.getQueryString();
	        Query sqlq = session.createSQLQuery(queryString);
	        int length = params.length;
	        for (int i = 0; i < length; ++i) {
	          sqlq.setParameter(i, params[i]);
	        }
	        int rtn = sqlq.executeUpdate();
	        return new Integer(rtn);
	      }
	    })).intValue();

	    return rs;
	}
	
	public <U>int save_Hibernate_Object(U u){
	    int rs = 0;
	    this.getHibernateTemplate().merge(u);
	    rs = 1;
	    return rs;
	}
	
	public <U> Object save_Hibernate_ObjResult(U u) {
		return this.getHibernateTemplate().merge(u);
	}
	
	public int save_Hibernate_ComposedQuery(final String composedSQL,final Object[] params){
		int rs = 0;
		rs = ((Integer)this.getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query sqlQuery = session.createSQLQuery(composedSQL);
				if(params != null){
					for(int i=0 ; i<params.length ; i++){
						sqlQuery.setParameter(i, params[i]);
					}
				}
				int rtn = sqlQuery.executeUpdate();
				return rtn;
			}
		})).intValue();
		return rs;
	}
	
	
	public int update_Hibernate_NamedQuery(final String queryID, final Object[] params){
	    int rs = 0;

	    rs = ((Integer)getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
	      public Object doInHibernate(Session session) throws HibernateException {
	        Query queryCMd = session.getNamedQuery(queryID);
	        String queryString = queryCMd.getQueryString();
	        Query sqlq = session.createSQLQuery(queryString);
	        int length = params.length;
	        for (int i = 0; i < length; ++i) {
	          sqlq.setParameter(i, params[i]);
	        }
	        int rtn = sqlq.executeUpdate();
	        return new Integer(rtn);
	      }
	    })).intValue();

	    return rs;
	}
	
	public <U>int update_Hibernate_Object(U u){
	    int rs = 0;
	    this.getHibernateTemplate().merge(u);
	    rs = 1;
	    return rs;
	}
	
	public int update_Hibernate_ComposedQuery(final String composedSQL,final Object[] params){
		int rs = 0;
		rs = ((Integer)this.getHibernateTemplate().executeWithNativeSession(new HibernateCallback() {
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query sqlQuery = session.createSQLQuery(composedSQL);
				if(params != null){
					for(int i=0 ; i<params.length ; i++){
						sqlQuery.setParameter(i, params[i]);
					}
				}
				int rtn = sqlQuery.executeUpdate();
				return rtn;
			}
		})).intValue();
		return rs;
	}
	
	public List<T> findList_Hibernate_D_ComposedHQL(String composedHQL,FilterInfo filters){
		String filterItemSql = CommonOperate.getFilterStr(filters,true);
		if(filterItemSql!=null && filterItemSql.length() > 0){
		
			if(composedHQL.toLowerCase().indexOf("where") < 0){
				composedHQL = composedHQL +" where ";
			}else{
				composedHQL = composedHQL +" and ";
			}
			
		}
		String hql = composedHQL + filterItemSql;
		//System.out.println(hql);
		return (List<T>) this.getHibernateTemplate().find(hql,CommonOperate.fillQueryValueArr(filters));
	}
	
	
	public int findCount_Hibernate_D_ComposedHQL(String composedHQL,FilterInfo filters){
		String filterItemSql = CommonOperate.getFilterStr(filters,true);
		if(filterItemSql!=null && filterItemSql.length() > 0){
		
			if(composedHQL.toLowerCase().indexOf("where") < 0){
				composedHQL = composedHQL +" where ";
			}else{
				composedHQL = composedHQL +" and ";
			}
			
		}
		String hql = composedHQL + filterItemSql;
		return new Integer(String.valueOf(this.getHibernateTemplate().find(hql,CommonOperate.fillQueryValueArr(filters)).get(0)));
	}
	
	public QueryResult queryPage_Hibernate_D_ComposedHQL(String composedListHQL,String composedCountHQL,final FilterInfo filters ,final PagingBean pageBean){
		QueryResult queryResult = new QueryResult();
		 long l1 = System.currentTimeMillis();		
		 
		 //lizhenzhen2014.11.24
         //修改的内容：1：将final String listHql = this.composeHQL_H(composedListHQL, filters,true);改为String temphql=this.composeHQL_H(composedListHQL, filters,true);
		 //        2:添加String [] temp=temphql.split(" ");和if(temp[1].equals("LoginLogBean")){ temphql=composedListHQL+" order by l.loginDate desc";}
		//及final String listHql = this.composeHQL_H(composedListHQL, filters,true);final String listHql=temphql;
		 
		 //修改begin
		// final String listHql = this.composeHQL_H(composedListHQL, filters,true);
		String temphql=this.composeHQL_H(composedListHQL, filters,true);
		String [] temp=temphql.split(" ");
		//if(temp[1].equals("LoginLogBean")){ temphql=composedListHQL+" order by l.loginDate desc";}
		final String listHql=temphql;
		//System.out.println(temphql);
		//end
		String countHql = this.composeHQL(composedCountHQL, filters,false);		
		List resultList = this.getHibernateTemplate().executeFind(new HibernateCallback() {		
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				//System.out.println(listHql);
				Query query=CommonOperate.fillQueryValue(filters, session.createQuery(listHql));
				//Map map = CommonOperate.fillQueryValue(filters);
//				for(Object obj : CommonOperate.fillQueryValue(filters).keySet()){
//					
//					query.setParameter(obj, map.get(obj));
//				}
				List result = query.setFirstResult((pageBean.getIndexPage() - 1)
				* pageBean.getShowRow()).setMaxResults(pageBean.getShowRow()).list();
				//setFirstResult(pageBean.getBeginRecord()).setMaxResults(pageBean.getShowRow())
				return result;

			}
		});
		//System.out.println(this.getHibernateTemplate().find("select count(*) from cn.com.genius.product.model.ProductBean",null));
		int count = 0;
		List list = this.getHibernateTemplate().find(countHql,CommonOperate.fillQueryValueArr(filters));
		if(list != null && list.size()>0){
			count = new Integer(String.valueOf(list.get(0)));
		}
		
		queryResult.setTotalRecordNumber(count);
		queryResult.setResultList(resultList);
		long l2 = System.currentTimeMillis();
		this.logger.info("Execute query time:" + (l2 - l1) + "ms");  
		return queryResult;
	}
	
	public  List findListObj_Hibernate_D_ComposedHQL(String composedListHQL,final FilterInfo filters ){
		final String listHql = this.composeHQL_H(composedListHQL, filters,true);
		List resultList = this.getHibernateTemplate().executeFind(new HibernateCallback() {
			
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query=CommonOperate.fillQueryValue(filters, session.createQuery(listHql));
//				Map map = CommonOperate.fillQueryValue(filters);
//				for(Object obj : CommonOperate.fillQueryValue(filters).keySet()){
//					
//					query.setParameter(obj, map.get(obj));
//				}
				List result = query.list();
				return result;

			}
		});
		
		return resultList;
	}
	
	
	//组装HQL查询条件,用于hibernateTemplate
	
	private String composeHQL(String composedHQL,FilterInfo filters ,boolean isSelect){
		String filterItemSql = CommonOperate.getFilterStr(filters,isSelect);
		if(filters.getAllFilterItems()!=null && filters.getAllFilterItems().size() > 0){
		
			if(composedHQL.toLowerCase().indexOf("where") < 0){
				composedHQL = composedHQL +" where ";
			}else{
				composedHQL = composedHQL +" and ";
			}
			
		}
		String hql = composedHQL + filterItemSql;
		return hql;
	}
	
	//组装HQL查询条件,用于hibernate中的方法用
	
	private String composeHQL_H(String composedHQL,FilterInfo filters ,boolean isSelect){
		
		String filterItemSql = CommonOperate.getFilterStr_H(filters,isSelect);
		if(filters !=null&&filters.getAllFilterItems()!=null && filters.getAllFilterItems().size() > 0){
		
			if(composedHQL.toLowerCase().indexOf("where") < 0){
				composedHQL = composedHQL +" where ";
			}else{
				composedHQL = composedHQL +" and ";
			}
			
		}
		String hql = composedHQL + filterItemSql;
		return hql;
	}
	public List queryListOfJdbcTemplate(String sql) {
		return jdbcTemplate.queryForList(sql);
	}

	


}
